package cate.game.pvp.pointrace.timer;

import cate.game.event.pointrace.PointRaceTimerEvent.EventType;
import cate.game.framework.Selector;
import cate.game.framework.timer.FIFOTimerTask;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.time.DateTool;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.util.Objects;
import java.util.StringJoiner;
import java.util.function.Consumer;

@ToString(exclude = "settingsConsumer")
public class PointRaceTimerTask extends FIFOTimerTask {

    public static final Consumer<Settings> DEFAULT_SETTINGS_CONSUMER = (s) -> {
    };

    private final Settings settings;
    @JsonIgnore
    private final Consumer<Settings> settingsConsumer;

    public PointRaceTimerTask(Settings settings, Consumer<Settings> settingsConsumer) {
        super(settings.triggerTimeMs);
        this.settings = settings;
        this.settingsConsumer = settingsConsumer;
    }

    @FunctionalInterface
    public interface Creator {
        PointRaceTimerTask createTimerTask(Settings settings);
    }

    @FunctionalInterface
    public interface SettingsConsumerSelector
            extends Selector<Consumer<Settings>, Settings> {
    }

    @NoArgsConstructor
    @Data
    public static class Settings {
        private int id;
        private int season;
        private int day;
        private long triggerTimeMs;
        private EventType eventType = EventType.OPEN;

        public static Settings of(int day, long triggerTimeMs, EventType eventType) {
            return of(1, 1, day, triggerTimeMs, eventType);
        }

        public static Settings of(int id, int season, int day, long triggerTimeMs, EventType eventType) {
            Settings settings = new Settings();
            settings.setId(id);
            settings.setSeason(season);
            settings.setDay(day);
            settings.setTriggerTimeMs(triggerTimeMs);
            settings.setEventType(eventType);
            return settings;
        }

        @Override
        public String toString() {
            return new StringJoiner(", ", Settings.class.getSimpleName() + "[", "]")
                    .add("id=" + id)
                    .add("season=" + season)
                    .add("day=" + day)
                    .add("triggerTimeMs=" + DateTool.instance().format(triggerTimeMs))
                    .add("eventType=" + eventType)
                    .toString();
        }
    }

    @Override
    public void run() {
        if (Objects.nonNull(this.settingsConsumer)) {
            this.settingsConsumer.accept(this.settings);
        }
        setDone(true);
    }
}
